import tkinter as tk
from tkinter import ttk, messagebox, filedialog, scrolledtext
import os
import git
import json
import threading
import requests
from datetime import datetime

class GiteeUploader:
    def __init__(self, root):
        self.root = root
        self.root.title("Gitee代码推送工具 V1.0.8                吾爱破解 @ 拉轰真人")
        
        # 设置窗口图标 - 修复图标路径问题
        icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "icon.ico")
        try:
            if os.path.exists(icon_path):
                self.root.iconbitmap(icon_path)
            else:
                # 尝试相对路径
                self.root.iconbitmap("icon.ico")
        except Exception as e:
            # 静默忽略图标设置错误
            pass
        
        # 配置数据
        self.config_file = "gitee_config.json"
        self.config = self.load_config()
        
        # 设置窗口大小和位置
        window_size = self.config.get("window_size", "900x700")
        window_position = self.config.get("window_position", "")
        
        # 应用窗口配置
        if window_position and window_position != "":
            try:
                # 验证位置格式
                if "+" in window_position:
                    x, y = window_position.split("+")
                    x, y = int(x), int(y)
                    # 允许负值位置（窗口可能部分超出屏幕）
                    self.root.geometry(f"{window_size}+{window_position}")
                else:
                    self.root.geometry(window_size)
            except (ValueError, TypeError) as e:
                # 如果位置格式无效，只设置大小
                self.root.geometry(window_size)
        else:
            self.root.geometry(window_size)
        
        self.root.resizable(True, True)
        
        # 绑定窗口大小和位置变化事件
        self.root.bind('<Configure>', self.on_window_configure)
        
        # 创建界面
        self.create_widgets()
        self.load_repo_info()
        
        # 延迟保存窗口配置，避免初始化时的频繁保存
        self.root.after(1000, self.save_window_config)
        
        # 初始化Gitee仓库列表
        self.gitee_repos = []
        self.load_gitee_repos()
        
        # 创建自定义按钮样式
        # 不再需要，使用tk.Button直接设置颜色
    
    def load_config(self):
        """加载配置文件"""
        if os.path.exists(self.config_file):
            try:
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
            except:
                pass
        return {
            "repositories": [],
            "username": "",
            "email": "",
            "gitee_token": "",
            "gitee_username": "",
            "window_size": "900x700",
            "window_position": ""
        }
    
    def save_config(self):
        """保存配置文件"""
        with open(self.config_file, 'w', encoding='utf-8') as f:
            json.dump(self.config, f, ensure_ascii=False, indent=2)
    
    def create_widgets(self):
        """创建界面组件"""
        # 创建主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 配置Git用户信息
        config_frame = ttk.LabelFrame(main_frame, text="Git用户配置", padding="5")
        config_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        
        ttk.Label(config_frame, text="用户名:").grid(row=0, column=0, sticky=tk.W, padx=(0, 5))
        self.username_var = tk.StringVar(value=self.config.get("username", ""))
        self.username_entry = ttk.Entry(config_frame, textvariable=self.username_var, width=30)
        self.username_entry.grid(row=0, column=1, sticky=tk.W, padx=(0, 10))
        
        ttk.Label(config_frame, text="邮箱:").grid(row=0, column=2, sticky=tk.W, padx=(0, 5))
        self.email_var = tk.StringVar(value=self.config.get("email", ""))
        self.email_entry = ttk.Entry(config_frame, textvariable=self.email_var, width=30)
        self.email_entry.grid(row=0, column=3, sticky=tk.W)
        
        # Gitee配置
        gitee_config_frame = ttk.LabelFrame(main_frame, text="Gitee配置", padding="5")
        gitee_config_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        
        ttk.Label(gitee_config_frame, text="Gitee用户名:").grid(row=0, column=0, sticky=tk.W, padx=(0, 5))
        self.gitee_username_var = tk.StringVar(value=self.config.get("gitee_username", ""))
        self.gitee_username_entry = ttk.Entry(gitee_config_frame, textvariable=self.gitee_username_var, width=20)
        self.gitee_username_entry.grid(row=0, column=1, sticky=tk.W, padx=(0, 10))
        
        ttk.Label(gitee_config_frame, text="访问令牌:").grid(row=0, column=2, sticky=tk.W, padx=(0, 5))
        self.gitee_token_var = tk.StringVar(value=self.config.get("gitee_token", ""))
        self.gitee_token_entry = ttk.Entry(gitee_config_frame, textvariable=self.gitee_token_var, width=30, show="*")
        self.gitee_token_entry.grid(row=0, column=3, sticky=tk.W, padx=(0, 10))
        
        ttk.Button(gitee_config_frame, text="测试连接", command=self.test_gitee_connection).grid(row=0, column=4, padx=(0, 5))
        tk.Button(gitee_config_frame, text="获取仓库列表", command=self.fetch_gitee_repos, 
                 bg='#44aa44', fg='white', relief='raised', bd=2).grid(row=0, column=5, padx=(0, 5))
        ttk.Button(gitee_config_frame, text="调试信息", command=self.debug_gitee_info).grid(row=0, column=6, padx=(0, 5))
        
        # 仓库选择
        repo_frame = ttk.LabelFrame(main_frame, text="仓库管理", padding="5")
        repo_frame.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        
        ttk.Label(repo_frame, text="仓库路径:").grid(row=0, column=0, sticky=tk.W, padx=(0, 5))
        self.repo_path_var = tk.StringVar()
        self.repo_path_entry = ttk.Entry(repo_frame, textvariable=self.repo_path_var, width=50)
        self.repo_path_entry.grid(row=0, column=1, sticky=(tk.W, tk.E), padx=(0, 5))
        
        ttk.Button(repo_frame, text="浏览", command=self.browse_repo).grid(row=0, column=2, padx=(0, 5))
        ttk.Button(repo_frame, text="添加仓库", command=self.add_repository).grid(row=0, column=3, padx=(0, 5))
        ttk.Button(repo_frame, text="初始化Git仓库", command=self.init_git_repository).grid(row=0, column=4, padx=(0, 5))
        ttk.Button(repo_frame, text="删除仓库", command=self.remove_repository).grid(row=0, column=5)
        
        # 仓库状态显示
        self.repo_status_label = ttk.Label(repo_frame, text="", foreground="gray")
        self.repo_status_label.grid(row=1, column=0, columnspan=6, sticky=tk.W, pady=(5, 0))
        
        # 绑定路径变化事件
        self.repo_path_var.trace('w', self.on_repo_path_change)
        
        # 仓库列表
        ttk.Label(repo_frame, text="已保存的仓库:").grid(row=2, column=0, sticky=tk.W, pady=(15, 5))
        self.repo_listbox = tk.Listbox(repo_frame, height=4)
        self.repo_listbox.grid(row=3, column=0, columnspan=5, sticky=(tk.W, tk.E), pady=(5, 0))
        self.repo_listbox.bind('<<ListboxSelect>>', self.on_repo_select)
        
        # Gitee仓库管理
        gitee_repo_frame = ttk.LabelFrame(main_frame, text="Gitee远程仓库管理", padding="5")
        gitee_repo_frame.grid(row=3, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        
        # Gitee仓库操作按钮
        gitee_button_frame = ttk.Frame(gitee_repo_frame)
        gitee_button_frame.grid(row=0, column=0, columnspan=2, pady=(0, 10))
        
        ttk.Button(gitee_button_frame, text="添加Gitee仓库", command=self.add_gitee_repo).grid(row=0, column=0, padx=(0, 5))
        ttk.Button(gitee_button_frame, text="刷新仓库列表", command=self.refresh_gitee_repos).grid(row=0, column=1, padx=(0, 5))
        ttk.Button(gitee_button_frame, text="删除远程仓库", command=self.remove_gitee_repo).grid(row=0, column=2, padx=(0, 5))
        ttk.Button(gitee_button_frame, text="检查远程配置", command=self.check_remote_config).grid(row=0, column=3, padx=(0, 5))
        ttk.Button(gitee_button_frame, text="修复远程仓库", command=self.fix_remote_repo).grid(row=0, column=4, padx=(0, 5))
        
        # Gitee仓库列表
        ttk.Label(gitee_repo_frame, text="Gitee远程仓库:").grid(row=1, column=0, sticky=tk.W, pady=(10, 0))
        self.gitee_repo_listbox = tk.Listbox(gitee_repo_frame, height=4)
        self.gitee_repo_listbox.grid(row=2, column=0, columnspan=4, sticky=(tk.W, tk.E), pady=(5, 0))
        self.gitee_repo_listbox.bind('<<ListboxSelect>>', self.on_gitee_repo_select)
        
        # Git操作
        git_frame = ttk.LabelFrame(main_frame, text="Git操作", padding="5")
        git_frame.grid(row=4, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        
        # 操作按钮
        button_frame = ttk.Frame(git_frame)
        button_frame.grid(row=0, column=0, columnspan=2, pady=(0, 10))
        
        # 左侧按钮组
        ttk.Button(button_frame, text="添加所有文件", command=self.add_all_files).grid(row=0, column=0, padx=(0, 5))
        ttk.Button(button_frame, text="提交更改", command=self.commit_changes).grid(row=0, column=1, padx=(0, 5))
        ttk.Button(button_frame, text="推送到远程", command=self.push_to_remote).grid(row=0, column=2, padx=(0, 5))
        
        # 分隔符
        separator = ttk.Separator(button_frame, orient='vertical')
        separator.grid(row=0, column=3, padx=10, sticky='ns')
        
        # 中间按钮组
        tk.Button(button_frame, text="检查状态", command=self.check_status, 
                 bg='#44aa44', fg='white', relief='raised', bd=2).grid(row=0, column=4, padx=(0, 5))
        tk.Button(button_frame, text="一键推送", command=self.one_click_push, 
                 bg='#44aa44', fg='white', relief='raised', bd=2).grid(row=0, column=5, padx=(0, 5))
        
        # 分隔符
        separator2 = ttk.Separator(button_frame, orient='vertical')
        separator2.grid(row=0, column=6, padx=10, sticky='ns')
        
        # 右侧按钮组（红色背景）
        tk.Button(button_frame, text="拉取远程", command=self.pull_from_remote, 
                 bg='#ff4444', fg='white', relief='raised', bd=2).grid(row=0, column=7, padx=(0, 5))
        tk.Button(button_frame, text="强制同步", command=self.force_sync_remote, 
                 bg='#ff4444', fg='white', relief='raised', bd=2).grid(row=0, column=8, padx=(0, 5))
        
        # 提交信息
        ttk.Label(git_frame, text="提交信息:").grid(row=1, column=0, sticky=tk.W, pady=(10, 0))
        self.commit_msg_var = tk.StringVar(value="更新代码")
        self.commit_msg_entry = ttk.Entry(git_frame, textvariable=self.commit_msg_var, width=60)
        self.commit_msg_entry.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(5, 0))
        
        # 操作日志显示
        status_frame = ttk.LabelFrame(main_frame, text="操作日志", padding="5")
        status_frame.grid(row=5, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 10))
        
        self.status_text = scrolledtext.ScrolledText(status_frame, height=12, width=80)
        self.status_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 设置默认文本颜色为蓝色
        self.status_text.tag_configure("default", foreground="blue")
        self.status_text.tag_configure("operation", foreground="red")
        self.status_text.tag_configure("file_list", foreground="green")
        
        # 配置网格权重
        main_frame.columnconfigure(0, weight=1)
        main_frame.rowconfigure(5, weight=1)
        repo_frame.columnconfigure(1, weight=1)
        gitee_repo_frame.columnconfigure(0, weight=1)
        git_frame.columnconfigure(0, weight=1)
        status_frame.columnconfigure(0, weight=1)
        status_frame.rowconfigure(0, weight=1)
        
        # 绑定保存配置事件
        self.username_entry.bind('<FocusOut>', self.save_user_config)
        self.email_entry.bind('<FocusOut>', self.save_user_config)
        self.gitee_username_entry.bind('<FocusOut>', self.save_gitee_config)
        self.gitee_token_entry.bind('<FocusOut>', self.save_gitee_config)
        
        # 初始化仓库状态显示
        self.update_repo_status()
        
        # 初始化Gitee仓库列表
        self.gitee_repos = []
        self.load_gitee_repos()
        
        # 延迟保存窗口配置，避免初始化时的频繁保存
        self.root.after(1000, self.save_window_config)
    
    def save_gitee_config(self, event=None):
        """保存Gitee配置"""
        self.config["gitee_username"] = self.gitee_username_var.get()
        self.config["gitee_token"] = self.gitee_token_var.get()
        self.save_config()
    
    def test_gitee_connection(self):
        """测试Gitee连接"""
        def run_test():
            username = self.gitee_username_var.get().strip()
            token = self.gitee_token_var.get().strip()
            
            if not username or not token:
                messagebox.showwarning("警告", "请输入Gitee用户名和访问令牌")
                return
            
            try:
                self.log_message("测试Gitee连接...", "operation")
                headers = {"Authorization": f"token {token}"}
                response = requests.get(f"https://gitee.com/api/v5/user", headers=headers, timeout=10)
                
                if response.status_code == 200:
                    user_info = response.json()
                    self.log_message(f"连接成功！用户: {user_info.get('name', username)}")
                    self.root.after(0, lambda: messagebox.showinfo("成功", "Gitee连接测试成功！"))
                else:
                    error_msg = f"连接失败: HTTP {response.status_code}"
                    if response.status_code == 401:
                        error_msg = "认证失败，请检查用户名和访问令牌"
                    elif response.status_code == 403:
                        error_msg = "权限不足，请检查访问令牌权限"
                    
                    self.log_message(error_msg)
                    self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
                    
            except requests.exceptions.Timeout:
                error_msg = "连接超时，请检查网络连接"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
            except requests.exceptions.ConnectionError:
                error_msg = "网络连接失败，请检查网络设置"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
            except Exception as e:
                error_msg = f"连接错误: {str(e)}"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
        
        threading.Thread(target=run_test, daemon=True).start()
    
    def debug_gitee_info(self):
        """调试Gitee信息"""
        def run_debug():
            username = self.gitee_username_var.get().strip()
            token = self.gitee_token_var.get().strip()
            
            if not username or not token:
                messagebox.showwarning("警告", "请输入Gitee用户名和访问令牌")
                return
            
            try:
                self.log_message("=== 开始调试Gitee信息 ===", "operation")
                headers = {"Authorization": f"token {token}"}
                
                # 1. 测试用户信息API
                self.log_message("1. 测试用户信息API...")
                response = requests.get("https://gitee.com/api/v5/user", headers=headers, timeout=10)
                if response.status_code == 200:
                    user_info = response.json()
                    self.log_message(f"   用户ID: {user_info.get('id')}")
                    self.log_message(f"   用户名: {user_info.get('login')}")
                    self.log_message(f"   显示名: {user_info.get('name')}")
                    self.log_message(f"   邮箱: {user_info.get('email')}")
                    self.log_message(f"   仓库数: {user_info.get('public_repos', 0)} 公开 + {user_info.get('total_private_repos', 0)} 私有")
                else:
                    self.log_message(f"   用户信息API失败: {response.status_code}")
                
                # 2. 测试当前用户仓库API
                self.log_message("2. 测试当前用户仓库API...")
                response = requests.get("https://gitee.com/api/v5/user/repos", headers=headers, timeout=10)
                if response.status_code == 200:
                    repos = response.json()
                    self.log_message(f"   当前用户仓库API成功，获取到 {len(repos)} 个仓库")
                    if repos:
                        first_repo = repos[0]
                        self.log_message(f"   示例仓库: {first_repo.get('full_name')} (私有: {first_repo.get('private')})")
                else:
                    self.log_message(f"   当前用户仓库API失败: {response.status_code}")
                    try:
                        error_detail = response.json()
                        self.log_message(f"   错误详情: {error_detail}")
                    except:
                        self.log_message(f"   响应内容: {response.text[:200]}")
                
                # 3. 测试指定用户仓库API
                self.log_message("3. 测试指定用户仓库API...")
                response = requests.get(f"https://gitee.com/api/v5/users/{username}/repos", headers=headers, timeout=10)
                if response.status_code == 200:
                    repos = response.json()
                    self.log_message(f"   指定用户仓库API成功，获取到 {len(repos)} 个仓库")
                else:
                    self.log_message(f"   指定用户仓库API失败: {response.status_code}")
                    try:
                        error_detail = response.json()
                        self.log_message(f"   错误详情: {error_detail}")
                    except:
                        self.log_message(f"   响应内容: {response.text[:200]}")
                
                # 4. 检查令牌权限
                self.log_message("4. 检查令牌权限...")
                self.log_message(f"   当前配置用户名: {username}")
                self.log_message(f"   令牌长度: {len(token)} 字符")
                self.log_message(f"   令牌格式: {'✓ 正确' if len(token) >= 20 else '⚠ 可能过短'}")
                
                self.log_message("=== 调试完成 ===")
                self.root.after(0, lambda: messagebox.showinfo("调试完成", "请查看状态信息区域的调试输出"))
                
            except Exception as e:
                error_msg = f"调试过程出错: {str(e)}"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
        
        threading.Thread(target=run_debug, daemon=True).start()
    

    
    def fetch_gitee_repos(self):
        """获取Gitee仓库列表"""
        def run_fetch():
            username = self.gitee_username_var.get().strip()
            token = self.gitee_token_var.get().strip()
            
            if not username or not token:
                messagebox.showwarning("警告", "请输入Gitee用户名和访问令牌")
                return
            
            try:
                self.log_message("获取Gitee仓库列表...", "operation")
                self.log_message(f"使用用户名: {username}")
                
                headers = {"Authorization": f"token {token}"}
                
                # 首先尝试获取当前用户的仓库（使用 /user/repos）
                self.log_message("尝试获取当前用户仓库...", "operation")
                response = requests.get(
                    "https://gitee.com/api/v5/user/repos",
                    headers=headers,
                    params={"per_page": 100, "page": 1},
                    timeout=10
                )
                
                if response.status_code == 200:
                    repos = response.json()
                    self.gitee_repos = []
                    
                    for repo in repos:
                        try:
                            # 构建仓库信息，使用更安全的方式获取字段
                            repo_info = {
                                "name": repo.get("name", ""),
                                "full_name": repo.get("full_name", ""),
                                "html_url": repo.get("html_url", ""),
                                "clone_url": repo.get("clone_url", ""),
                                "ssh_url": repo.get("ssh_url", ""),
                                "description": repo.get("description", ""),
                                "private": repo.get("private", False)
                            }
                            
                            # 检查必需字段
                            if repo_info["name"] and repo_info["full_name"]:
                                self.gitee_repos.append(repo_info)
                                self.log_message(f"添加仓库: {repo_info['full_name']}")
                            else:
                                self.log_message(f"跳过无效仓库: 缺少名称信息")
                                
                        except Exception as e:
                            self.log_message(f"跳过无效仓库数据: {e}")
                            continue
                    
                    self.log_message(f"获取到 {len(self.gitee_repos)} 个仓库")
                    # 在主线程中更新UI
                    self.root.after(0, self.load_gitee_repos)
                    self.root.after(0, lambda: messagebox.showinfo("成功", f"成功获取到 {len(self.gitee_repos)} 个仓库"))
                    return
                
                # 如果获取当前用户仓库失败，尝试获取指定用户的仓库
                self.log_message("获取当前用户仓库失败，尝试获取指定用户仓库...", "operation")
                response = requests.get(
                    f"https://gitee.com/api/v5/users/{username}/repos",
                    headers=headers,
                    params={"per_page": 100, "page": 1, "type": "all"},
                    timeout=10
                )
                
                if response.status_code == 200:
                    repos = response.json()
                    self.gitee_repos = []
                    
                    # 调试：显示第一个仓库的完整结构
                    if repos:
                        self.log_message(f"指定用户仓库数据结构: {list(repos[0].keys())}")
                        self.log_message(f"示例仓库数据: {repos[0]}")
                    
                    for repo in repos:
                        try:
                            # 构建仓库信息，使用更安全的方式获取字段
                            repo_info = {
                                "name": repo.get("name", ""),
                                "full_name": repo.get("full_name", ""),
                                "html_url": repo.get("html_url", ""),
                                "clone_url": repo.get("clone_url", ""),
                                "ssh_url": repo.get("ssh_url", ""),
                                "description": repo.get("description", ""),
                                "private": repo.get("private", False)
                            }
                            
                            # 检查必需字段
                            if repo_info["name"] and repo_info["full_name"]:
                                self.gitee_repos.append(repo_info)
                                self.log_message(f"添加仓库: {repo_info['full_name']}")
                            else:
                                self.log_message(f"跳过无效仓库: 缺少名称信息")
                                
                        except Exception as e:
                            self.log_message(f"跳过无效仓库数据: {e}")
                            continue
                    
                    self.log_message(f"获取到 {len(self.gitee_repos)} 个仓库")
                    # 在主线程中更新UI
                    self.root.after(0, self.load_gitee_repos)
                    self.root.after(0, lambda: messagebox.showinfo("成功", f"成功获取到 {len(self.gitee_repos)} 个仓库"))
                else:
                    # 尝试获取响应内容以了解具体错误
                    try:
                        error_detail = response.json()
                        self.log_message(f"API响应详情: {error_detail}")
                    except:
                        self.log_message(f"响应内容: {response.text[:200]}")
                    
                    error_msg = f"获取仓库失败: HTTP {response.status_code}"
                    if response.status_code == 401:
                        error_msg = "认证失败，请检查用户名和访问令牌"
                    elif response.status_code == 403:
                        error_msg = "权限不足，请检查访问令牌权限"
                    elif response.status_code == 404:
                        error_msg = "用户不存在或没有公开仓库"
                    
                    self.log_message(error_msg)
                    self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
                    
            except requests.exceptions.Timeout:
                error_msg = "请求超时，请检查网络连接"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
            except requests.exceptions.ConnectionError:
                error_msg = "网络连接失败，请检查网络设置"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
            except Exception as e:
                error_msg = f"获取仓库错误: {str(e)}"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
        
        threading.Thread(target=run_fetch, daemon=True).start()
    
    def load_gitee_repos(self):
        """加载Gitee仓库到列表"""
        self.gitee_repo_listbox.delete(0, tk.END)
        for repo in self.gitee_repos:
            private_mark = " [私有]" if repo["private"] else ""
            self.gitee_repo_listbox.insert(tk.END, f"{repo['full_name']}{private_mark}")
    
    def refresh_gitee_repos(self):
        """刷新Gitee仓库列表"""
        self.fetch_gitee_repos()
    
    def on_gitee_repo_select(self, event):
        """Gitee仓库选择事件"""
        selection = self.gitee_repo_listbox.curselection()
        if selection:
            selected_repo = self.gitee_repos[selection[0]]
            # 可以在这里显示仓库详细信息
            self.log_message(f"选择仓库: {selected_repo['full_name']}")
    
    def add_gitee_repo(self):
        """添加Gitee仓库到当前Git仓库"""
        selection = self.gitee_repo_listbox.curselection()
        if not selection:
            messagebox.showwarning("警告", "请先选择一个Gitee仓库")
            return
        
        if not self.repo_path_var.get().strip():
            messagebox.showwarning("警告", "请先选择本地Git仓库")
            return
        
        selected_repo = self.gitee_repos[selection[0]]
        
        def run_add():
            try:
                repo_path = self.repo_path_var.get().strip()
                repo = git.Repo(repo_path)
                
                # 检查是否已经存在该远程仓库
                remote_name = "origin"  # 使用标准的origin名称
                existing_remotes = [r.name for r in repo.remotes]
                
                # 验证并清理clone_url
                clone_url = selected_repo["clone_url"]
                if clone_url:
                    # 移除URL末尾的斜杠和空格
                    clone_url = clone_url.rstrip('/ ').strip()
                    self.log_message(f"清理后的URL: {clone_url}")
                else:
                    # 如果没有clone_url，尝试构建
                    username = self.gitee_username_var.get().strip()
                    repo_name = selected_repo["name"]
                    clone_url = f"https://gitee.com/{username}/{repo_name}.git"
                    self.log_message(f"构建的URL: {clone_url}")
                
                if remote_name in existing_remotes:
                    # 更新现有远程仓库
                    self.log_message(f"更新远程仓库 {remote_name}...")
                    remote = repo.remote(remote_name)
                    remote.set_url(clone_url)
                else:
                    # 添加新的远程仓库
                    self.log_message(f"添加远程仓库 {remote_name}...")
                    repo.create_remote(remote_name, clone_url)
                
                self.log_message(f"成功添加/更新远程仓库: {selected_repo['full_name']}")
                self.log_message(f"URL: {clone_url}")
                
                # 显示当前所有远程仓库
                self.log_message("当前远程仓库配置:")
                for r in repo.remotes:
                    self.log_message(f"  {r.name}: {r.url}")
                
                # 测试远程仓库连接
                try:
                    self.log_message("测试远程仓库连接...", "operation")
                    remote = repo.remote(remote_name)
                    remote.fetch()
                    self.log_message("✓ 远程仓库连接成功")
                except Exception as e:
                    self.log_message(f"⚠ 远程仓库连接测试失败: {str(e)}")
                    self.log_message("建议：检查网络连接和仓库权限")
                
                self.root.after(0, lambda: messagebox.showinfo("成功", f"成功添加远程仓库: {selected_repo['full_name']}"))
                
            except Exception as e:
                error_msg = f"添加远程仓库失败: {str(e)}"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
        
        threading.Thread(target=run_add, daemon=True).start()
    
    def remove_gitee_repo(self):
        """删除Gitee远程仓库"""
        if not self.repo_path_var.get().strip():
            messagebox.showwarning("警告", "请先选择本地Git仓库")
            return
        
        def run_remove():
            try:
                repo_path = self.repo_path_var.get().strip()
                repo = git.Repo(repo_path)
                
                # 显示现有远程仓库供选择
                existing_remotes = [r.name for r in repo.remotes]
                
                if not existing_remotes:
                    messagebox.showinfo("提示", "当前仓库没有配置远程仓库")
                    return
                
                # 这里可以创建一个选择对话框，暂时删除名为"origin"的远程仓库
                remote_name = "origin"
                if remote_name in existing_remotes:
                    self.log_message(f"删除远程仓库 {remote_name}...")
                    repo.delete_remote(remote_name)
                    self.log_message(f"成功删除远程仓库: {remote_name}")
                    self.root.after(0, lambda: messagebox.showinfo("成功", f"成功删除远程仓库: {remote_name}"))
                else:
                    self.root.after(0, lambda: messagebox.showinfo("提示", f"未找到名为 '{remote_name}' 的远程仓库"))
                
            except Exception as e:
                error_msg = f"删除远程仓库失败: {str(e)}"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
        
        threading.Thread(target=run_remove, daemon=True).start()
    
    def check_remote_config(self):
        """检查远程仓库配置"""
        if not self.repo_path_var.get().strip():
            messagebox.showwarning("警告", "请先选择本地Git仓库")
            return
        
        def run_check():
            try:
                repo_path = self.repo_path_var.get().strip()
                repo = git.Repo(repo_path)
                
                self.log_message("=== 检查远程仓库配置 ===", "operation")
                
                # 检查所有远程仓库
                if repo.remotes:
                    self.log_message("当前远程仓库配置:")
                    for remote in repo.remotes:
                        self.log_message(f"  {remote.name}: {remote.url}")
                        
                        # 测试远程仓库连接
                        try:
                            self.log_message(f"  测试连接 {remote.name}...", "operation")
                            # 获取远程分支信息
                            remote.fetch()
                            self.log_message(f"  ✓ {remote.name} 连接正常")
                        except Exception as e:
                            self.log_message(f"  ✗ {remote.name} 连接失败: {str(e)}")
                else:
                    self.log_message("当前仓库没有配置远程仓库")
                
                # 检查当前分支
                try:
                    current_branch = repo.active_branch.name
                    self.log_message(f"当前分支: {current_branch}")
                    
                    # 检查是否有对应的远程分支
                    if repo.remotes:
                        for remote in repo.remotes:
                            try:
                                remote_branches = [ref.name for ref in remote.refs]
                                if f"{remote.name}/{current_branch}" in remote_branches:
                                    self.log_message(f"  ✓ 远程分支 {remote.name}/{current_branch} 存在")
                                else:
                                    self.log_message(f"  ⚠ 远程分支 {remote.name}/{current_branch} 不存在")
                            except Exception as e:
                                self.log_message(f"  ✗ 无法检查远程分支: {str(e)}")
                except Exception as e:
                    self.log_message(f"无法获取当前分支信息: {str(e)}")
                
                self.log_message("=== 检查完成 ===")
                
            except Exception as e:
                error_msg = f"检查远程配置失败: {str(e)}"
                self.log_message(error_msg)
        
        threading.Thread(target=run_check, daemon=True).start()
    
    def fix_remote_repo(self):
        """修复远程仓库配置"""
        if not self.repo_path_var.get().strip():
            messagebox.showwarning("警告", "请先选择本地Git仓库")
            return
        
        def run_fix():
            try:
                repo_path = self.repo_path_var.get().strip()
                repo = git.Repo(repo_path)
                
                self.log_message("=== 开始修复远程仓库配置 ===", "operation")
                
                # 检查当前远程仓库配置
                if not repo.remotes:
                    self.log_message("当前仓库没有配置远程仓库")
                    self.root.after(0, lambda: messagebox.showinfo("提示", "当前仓库没有配置远程仓库，请先添加Gitee仓库"))
                    return
                
                # 显示当前配置
                self.log_message("当前远程仓库配置:")
                for remote in repo.remotes:
                    self.log_message(f"  {remote.name}: {remote.url}")
                
                # 获取Gitee仓库列表
                if not self.gitee_repos:
                    self.log_message("请先获取Gitee仓库列表")
                    self.root.after(0, lambda: messagebox.showwarning("警告", "请先获取Gitee仓库列表"))
                    return
                
                # 尝试找到匹配的仓库
                username = self.gitee_username_var.get().strip()
                if not username:
                    self.log_message("请先配置Gitee用户名")
                    self.root.after(0, lambda: messagebox.showwarning("警告", "请先配置Gitee用户名"))
                    return
                
                # 从当前路径推断仓库名称
                repo_name = os.path.basename(repo_path)
                self.log_message(f"推断的仓库名称: {repo_name}")
                
                # 查找匹配的Gitee仓库
                matching_repo = None
                for gitee_repo in self.gitee_repos:
                    if gitee_repo["name"].lower() == repo_name.lower():
                        matching_repo = gitee_repo
                        break
                
                if not matching_repo:
                    self.log_message("未找到匹配的Gitee仓库，请手动选择")
                    self.root.after(0, lambda: messagebox.showwarning("警告", "未找到匹配的Gitee仓库，请手动选择并添加"))
                    return
                
                self.log_message(f"找到匹配的Gitee仓库: {matching_repo['full_name']}")
                
                # 修复远程仓库URL
                remote_name = "origin"
                if remote_name in [r.name for r in repo.remotes]:
                    remote = repo.remote(remote_name)
                    
                    # 构建正确的URL - 使用Gitee仓库的实际用户名和仓库名
                    gitee_username = matching_repo["full_name"].split("/")[0]
                    gitee_repo_name = matching_repo["full_name"].split("/")[1]
                    correct_url = f"https://gitee.com/{gitee_username}/{gitee_repo_name}.git"
                    
                    self.log_message(f"修复URL: {remote.url} -> {correct_url}")
                    self.log_message(f"使用Gitee仓库信息: 用户名={gitee_username}, 仓库名={gitee_repo_name}")
                    
                    # 更新URL
                    remote.set_url(correct_url)
                    self.log_message(f"✓ 远程仓库URL已修复")
                    
                    # 测试连接
                    try:
                        self.log_message("测试修复后的连接...", "operation")
                        remote.fetch()
                        self.log_message("✓ 远程仓库连接成功")
                        self.root.after(0, lambda: messagebox.showinfo("成功", f"远程仓库已修复并连接成功！\n新URL: {correct_url}"))
                    except Exception as e:
                        self.log_message(f"⚠ 连接测试失败: {str(e)}")
                        self.root.after(0, lambda: messagebox.showwarning("警告", f"URL已修复，但连接测试失败: {str(e)}"))
                else:
                    self.log_message(f"未找到名为 '{remote_name}' 的远程仓库")
                    self.root.after(0, lambda: messagebox.showinfo("提示", f"未找到名为 '{remote_name}' 的远程仓库"))
                
                self.log_message("=== 修复完成 ===")
                
            except Exception as e:
                error_msg = f"修复远程仓库失败: {str(e)}"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
        
        threading.Thread(target=run_fix, daemon=True).start()
    
    def on_window_configure(self, event):
        """窗口大小和位置变化事件"""
        # 只处理主窗口的配置变化，忽略子组件的
        if event.widget == self.root:
            # 使用after延迟保存，避免频繁保存
            if hasattr(self, '_window_config_timer'):
                self.root.after_cancel(self._window_config_timer)
            self._window_config_timer = self.root.after(500, self.save_window_config)
    
    def save_window_config(self):
        """保存窗口配置 - 后台静默保存，不显示日志"""
        try:
            # 使用更可靠的方法获取窗口信息
            width = self.root.winfo_width()
            height = self.root.winfo_height()
            x = self.root.winfo_x()
            y = self.root.winfo_y()
            
            # 构建配置数据
            if width > 0 and height > 0:
                size_part = f"{width}x{height}"
                
                # 处理位置信息，允许负值（窗口可能部分超出屏幕）
                if x != 0 or y != 0:  # 只要不是默认位置(0,0)就保存
                    position_part = f"{x}+{y}"
                else:
                    position_part = ""
                
                # 检查配置是否有变化
                if (self.config.get("window_size") != size_part or 
                    self.config.get("window_position") != position_part):
                    
                    self.config["window_size"] = size_part
                    self.config["window_position"] = position_part
                    
                    # 后台保存到配置文件，不显示日志
                    self.save_config()
                
            # 静默处理，不显示任何日志信息
                
        except Exception as e:
            # 静默处理错误，不影响主程序运行
            pass
    
    def browse_repo(self):
        """浏览选择仓库路径"""
        path = filedialog.askdirectory(title="选择Git仓库")
        if path:
            self.repo_path_var.set(path)
    
    def init_git_repository(self):
        """初始化Git仓库"""
        path = self.repo_path_var.get().strip()
        if not path:
            messagebox.showwarning("警告", "请选择仓库路径")
            return
        
        # 检查路径是否存在
        if not os.path.exists(path):
            messagebox.showerror("错误", "选择的路径不存在")
            return
        
        # 检查是否已经是Git仓库
        if os.path.exists(os.path.join(path, '.git')):
            messagebox.showinfo("提示", "该路径已经是Git仓库")
            return
        
        # 确认初始化
        result = messagebox.askyesno(
            "初始化Git仓库", 
            f"确定要初始化Git仓库吗？\n\n"
            f"路径: {path}\n\n"
            "这将：\n"
            "• 创建新的Git仓库\n"
            "• 配置用户信息\n"
            "• 创建初始提交\n\n"
            "适合新项目使用。"
        )
        
        if not result:
            return
        
        def run_init():
            try:
                self.log_message(f"正在初始化Git仓库: {path}", "operation")
                
                # 初始化Git仓库
                repo = git.Repo.init(path)
                self.log_message("✓ Git仓库初始化成功")
                
                # 设置默认用户信息（如果已配置）
                if self.username_var.get():
                    repo.config_writer().set_value("user", "name", self.username_var.get()).release()
                    self.log_message(f"✓ 用户名已配置: {self.username_var.get()}")
                if self.email_var.get():
                    repo.config_writer().set_value("user", "email", self.email_var.get()).release()
                    self.log_message(f"✓ 邮箱已配置: {self.email_var.get()}")
                
                # 创建初始提交
                try:
                    # 检查是否有文件
                    files = [f for f in os.listdir(path) if f != '.git' and not f.startswith('.')]
                    if files:
                        # 添加所有文件（排除.git目录和隐藏文件）
                        for file in files:
                            file_path = os.path.join(path, file)
                            if os.path.isfile(file_path):
                                repo.index.add(file)
                                self.log_message(f"  添加文件: {file}")
                        
                        # 创建初始提交
                        commit_msg = "初始提交"
                        repo.index.commit(commit_msg)
                        self.log_message(f"✓ 初始提交创建成功: {commit_msg}")
                    else:
                        self.log_message("⚠ 目录为空，跳过文件添加")
                        
                        # 创建空的初始提交
                        repo.index.commit("初始提交 - 空仓库")
                        self.log_message("✓ 空仓库初始提交创建成功")
                        
                except Exception as e:
                    self.log_message(f"⚠ 初始提交创建失败: {str(e)}")
                    # 继续，不阻止仓库初始化
                
                # 自动添加到配置
                if path not in self.config["repositories"]:
                    self.config["repositories"].append(path)
                    self.save_config()
                    self.load_repo_info()
                    self.log_message("✓ 仓库已自动添加到配置")
                
                self.log_message("=== Git仓库初始化完成 ===")
                
                # 更新状态显示
                self.root.after(0, self.update_repo_status)
                
                self.root.after(0, lambda: messagebox.showinfo("成功", 
                    f"Git仓库初始化成功！\n\n"
                    f"路径: {path}\n"
                    f"状态: 已添加到配置\n"
                    f"下一步: 可以添加Gitee远程仓库并推送代码"))
                
            except Exception as e:
                error_msg = f"初始化Git仓库失败: {str(e)}"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
        
        threading.Thread(target=run_init, daemon=True).start()
    
    def on_repo_path_change(self, *args):
        """仓库路径变化事件"""
        self.update_repo_status()
    
    def update_repo_status(self):
        """更新仓库状态显示"""
        path = self.repo_path_var.get().strip()
        
        if not path:
            self.repo_status_label.config(text="", foreground="gray")
            return
        
        if not os.path.exists(path):
            self.repo_status_label.config(text="❌ 路径不存在", foreground="red")
            return
        
        if os.path.exists(os.path.join(path, '.git')):
            try:
                # 尝试打开Git仓库获取更多信息
                repo = git.Repo(path)
                current_branch = repo.active_branch.name
                remote_count = len(repo.remotes)
                
                status_text = f"✅ Git仓库 - 分支: {current_branch}"
                if remote_count > 0:
                    remote_names = [r.name for r in repo.remotes]
                    status_text += f"，远程: {', '.join(remote_names)}"
                
                self.repo_status_label.config(text=status_text, foreground="green")
            except Exception as e:
                self.repo_status_label.config(text="⚠️ Git仓库损坏", foreground="orange")
        else:
            self.repo_status_label.config(text="📁 普通文件夹 - 点击'初始化Git仓库'按钮创建Git仓库", foreground="blue")
    
    def add_repository(self):
        """添加仓库到配置"""
        path = self.repo_path_var.get().strip()
        if not path:
            messagebox.showwarning("警告", "请选择仓库路径")
            return
        
        # 检查路径是否存在
        if not os.path.exists(path):
            messagebox.showerror("错误", "选择的路径不存在")
            return
        
        # 检查是否为Git仓库
        if not os.path.exists(os.path.join(path, '.git')):
            # 询问是否要初始化为Git仓库
            result = messagebox.askyesno(
                "初始化Git仓库", 
                f"选择的路径不是Git仓库：\n{path}\n\n"
                "是否要将其初始化为新的Git仓库？\n\n"
                "注意：这将创建一个新的Git仓库，适合新项目。"
            )
            
            if result:
                # 调用初始化方法
                self.init_git_repository()
                return
            else:
                return
        
        # 添加到配置
        if path not in self.config["repositories"]:
            self.config["repositories"].append(path)
            self.save_config()
            self.load_repo_info()
            messagebox.showinfo("成功", "仓库已添加到配置")
        else:
            messagebox.showinfo("提示", "仓库已存在")
    
    def remove_repository(self):
        """从配置中删除仓库"""
        # 获取选中的仓库
        selection = self.repo_listbox.curselection()
        if not selection:
            messagebox.showwarning("警告", "请先选择要删除的仓库")
            return
        
        selected_index = selection[0]
        selected_path = self.config["repositories"][selected_index]
        
        # 确认删除
        confirm = messagebox.askyesno("确认删除", f"确定要删除仓库:\n{selected_path}\n\n注意：这只是从配置列表中删除，不会删除实际的文件夹。")
        if not confirm:
            return
        
        try:
            # 从配置中删除
            del self.config["repositories"][selected_index]
            self.save_config()
            
            # 如果删除的是当前选中的仓库，清空路径输入框
            if self.repo_path_var.get().strip() == selected_path:
                self.repo_path_var.set("")
            
            # 重新加载仓库列表
            self.load_repo_info()
            
            messagebox.showinfo("成功", f"仓库已从配置中删除:\n{selected_path}")
            
        except Exception as e:
            error_msg = f"删除仓库失败: {str(e)}"
            messagebox.showerror("错误", error_msg)
    
    def load_repo_info(self):
        """加载仓库信息到列表"""
        self.repo_listbox.delete(0, tk.END)
        for repo in self.config["repositories"]:
            self.repo_listbox.insert(tk.END, repo)
    
    def on_repo_select(self, event):
        """仓库选择事件"""
        selection = self.repo_listbox.curselection()
        if selection:
            selected_repo = self.config["repositories"][selection[0]]
            self.repo_path_var.set(selected_repo)
    
    def save_user_config(self, event=None):
        """保存用户配置"""
        self.config["username"] = self.username_var.get()
        self.config["email"] = self.email_var.get()
        self.save_config()
    
    def get_repo(self):
        """获取当前选择的仓库对象"""
        path = self.repo_path_var.get().strip()
        if not path:
            messagebox.showwarning("警告", "请选择仓库路径")
            return None
        
        try:
            return git.Repo(path)
        except Exception as e:
            messagebox.showerror("错误", f"无法打开仓库: {str(e)}")
            return None
    
    def log_message(self, message, message_type="default"):
        """记录日志消息
        
        Args:
            message: 日志消息内容
            message_type: 消息类型
                - "default": 普通内容（蓝色字体）
                - "operation": 操作提示类（红色字体）
                - "file_list": 文件列表（绿色字体）
        """
        timestamp = datetime.now().strftime("%H:%M:%S")
        
        # 插入消息
        self.status_text.insert(tk.END, f"[{timestamp}] {message}\n")
        
        # 应用颜色标签
        if message_type == "operation":
            # 获取最后插入的行
            last_line_start = self.status_text.index("end-2c linestart")
            last_line_end = self.status_text.index("end-1c")
            self.status_text.tag_add("operation", last_line_start, last_line_end)
        elif message_type == "file_list":
            # 获取最后插入的行
            last_line_start = self.status_text.index("end-2c linestart")
            last_line_end = self.status_text.index("end-1c")
            self.status_text.tag_add("file_list", last_line_start, last_line_end)
        else:
            # 获取最后插入的行
            last_line_start = self.status_text.index("end-2c linestart")
            last_line_end = self.status_text.index("end-1c")
            self.status_text.tag_add("default", last_line_start, last_line_end)
        
        self.status_text.see(tk.END)
        self.root.update()
    
    def check_status(self):
        """检查Git状态"""
        def run_check():
            repo = self.get_repo()
            if not repo:
                return
            
            try:
                self.log_message("检查Git状态...", "operation")
                
                # 检查是否有未提交的更改
                if repo.is_dirty():
                    self.log_message("发现未提交的更改:")
                    for item in repo.index.diff(None):
                        self.log_message(f"  修改: {item.a_path}")
                    for item in repo.untracked_files:
                        self.log_message(f"  未跟踪: {item}")
                else:
                    self.log_message("工作目录是干净的")
                
                # 检查远程分支
                try:
                    for remote in repo.remotes:
                        self.log_message(f"远程仓库: {remote.name} -> {remote.url}")
                except:
                    self.log_message("无法获取远程仓库信息")
                    
            except Exception as e:
                self.log_message(f"错误: {str(e)}")
        
        threading.Thread(target=run_check, daemon=True).start()
    
    def add_all_files(self):
        """添加所有文件到暂存区"""
        def run_add():
            repo = self.get_repo()
            if not repo:
                return
            
            try:
                self.log_message("添加所有文件到暂存区...", "operation")
                repo.index.add('*')
                self.log_message("文件已添加到暂存区")
            except Exception as e:
                self.log_message(f"错误: {str(e)}")
        
        threading.Thread(target=run_add, daemon=True).start()
    
    def commit_changes(self):
        """提交更改"""
        def run_commit():
            repo = self.get_repo()
            if not repo:
                return
            
            try:
                # 设置用户信息
                if self.username_var.get():
                    repo.config_writer().set_value("user", "name", self.username_var.get()).release()
                if self.email_var.get():
                    repo.config_writer().set_value("user", "email", self.email_var.get()).release()
                
                commit_msg = self.commit_msg_var.get().strip()
                if not commit_msg:
                    commit_msg = "更新代码"
                
                # 检查暂存区的文件状态
                self.log_message("检查暂存区文件状态...", "operation")
                
                # 获取暂存区的文件
                staged_files = []
                try:
                    # 获取已暂存的文件（修改的文件）
                    for item in repo.index.diff('HEAD'):
                        if item.a_path:
                            staged_files.append(("修改", item.a_path))
                    
                    # 获取新添加的文件（新增的文件）
                    for item in repo.index.diff('HEAD', staged=True):
                        if item.a_path and item.a_path not in [f[1] for f in staged_files]:
                            staged_files.append(("新增", item.a_path))
                    
                    # 如果是第一次提交，可能没有HEAD，尝试其他方法
                    if not staged_files:
                        # 检查工作目录状态
                        if repo.is_dirty():
                            # 获取已修改的文件
                            for item in repo.index.diff(None):
                                if item.a_path:
                                    staged_files.append(("修改", item.a_path))
                            
                            # 获取未跟踪的文件
                            for item in repo.untracked_files:
                                staged_files.append(("新增", item))
                except Exception as e:
                    # 如果上述方法失败，尝试备用方法
                    try:
                        # 检查工作目录状态
                        if repo.is_dirty():
                            # 获取已修改的文件
                            for item in repo.index.diff(None):
                                if item.a_path:
                                    staged_files.append(("修改", item.a_path))
                            
                            # 获取未跟踪的文件
                            for item in repo.untracked_files:
                                staged_files.append(("新增", item))
                    except:
                        pass
                
                # 显示文件列表
                if staged_files:
                    self.log_message("准备提交以下文件:")
                    for file_type, file_path in staged_files:
                        self.log_message(f"  {file_type}：{file_path}", "file_list")
                else:
                    self.log_message("没有检测到需要提交的文件")
                
                self.log_message(f"提交更改: {commit_msg}", "operation")
                repo.index.commit(commit_msg)
                self.log_message("提交成功")
                
            except Exception as e:
                self.log_message(f"错误: {str(e)}")
        
        threading.Thread(target=run_commit, daemon=True).start()
    
    def push_to_remote(self):
        """推送到远程仓库"""
        def run_push():
            repo = self.get_repo()
            if not repo:
                return
            
            try:
                self.log_message("推送到远程仓库...", "operation")
                
                # 获取当前分支
                current_branch = repo.active_branch.name
                self.log_message(f"当前分支: {current_branch}")
                
                # 推送到远程
                for remote in repo.remotes:
                    self.log_message(f"推送到 {remote.name}...", "operation")
                    remote.push(current_branch)
                    self.log_message(f"推送到 {remote.name} 成功")
                
            except Exception as e:
                self.log_message(f"错误: {str(e)}")
        
        threading.Thread(target=run_push, daemon=True).start()
    
    def pull_from_remote(self):
        """从远程仓库拉取更新"""
        def run_pull():
            repo = self.get_repo()
            if not repo:
                return
            
            # 检查是否有未提交的更改
            if repo.is_dirty():
                result = messagebox.askyesnocancel(
                    "检测到未提交的更改", 
                    "当前工作目录有未提交的更改，这可能导致合并冲突。\n\n"
                    "是否继续拉取？\n"
                    "• 是：继续拉取（可能需要手动解决冲突）\n"
                    "• 否：先提交当前更改\n"
                    "• 取消：取消操作"
                )
                if result is None:  # 取消
                    return
                elif result is False:  # 否，先提交
                    self.log_message("请先提交当前更改，然后再尝试拉取")
                    return
            
            try:
                self.log_message("从远程仓库拉取更新...", "operation")
                
                # 检查是否有远程仓库
                if not repo.remotes:
                    self.log_message("当前仓库没有配置远程仓库")
                    self.root.after(0, lambda: messagebox.showwarning("警告", "当前仓库没有配置远程仓库"))
                    return
                
                # 获取当前分支
                current_branch = repo.active_branch.name
                self.log_message(f"当前分支: {current_branch}")
                
                # 从所有远程仓库拉取
                for remote in repo.remotes:
                    try:
                        self.log_message(f"从 {remote.name} 拉取更新...", "operation")
                        
                        # 先获取远程信息
                        remote.fetch()
                        self.log_message(f"✓ 从 {remote.name} 获取远程信息成功")
                        
                        # 检查是否有远程分支
                        remote_branch = f"{remote.name}/{current_branch}"
                        if remote_branch in [ref.name for ref in remote.refs]:
                            self.log_message(f"找到远程分支: {remote_branch}", "operation")
                            
                            # 拉取并合并
                            try:
                                remote.pull(current_branch)
                                self.log_message(f"✓ 从 {remote.name} 拉取并合并成功")
                            except git.exc.GitCommandError as e:
                                if "refusing to merge unrelated histories" in str(e):
                                    self.log_message("⚠ 检测到不相关的历史记录，尝试强制合并...", "operation")
                                    try:
                                        # 使用 --allow-unrelated-histories 参数
                                        repo.git.pull(remote.name, current_branch, "--allow-unrelated-histories")
                                        self.log_message(f"✓ 强制合并成功")
                                    except Exception as force_error:
                                        error_msg = f"强制合并失败: {str(force_error)}"
                                        self.log_message(error_msg)
                                        # 提供重置选项
                                        reset_result = messagebox.askyesno(
                                            "合并失败", 
                                            f"强制合并失败: {str(force_error)}\n\n"
                                            "是否要重置本地仓库到远程状态？\n"
                                            "⚠ 警告：这将丢失所有本地提交历史！\n\n"
                                            "建议先备份重要文件。"
                                        )
                                        if reset_result:
                                            try:
                                                self.log_message("正在重置到远程状态...", "operation")
                                                # 重置到远程分支
                                                remote_branch_ref = f"{remote.name}/{current_branch}"
                                                repo.git.reset("--hard", remote_branch_ref)
                                                self.log_message("✓ 重置成功，本地仓库已同步到远程状态")
                                            except Exception as reset_error:
                                                self.log_message(f"重置失败: {str(reset_error)}")
                                                self.root.after(0, lambda: messagebox.showerror("重置失败", f"重置失败: {str(reset_error)}"))
                                        continue
                                else:
                                    raise e
                            
                            # 显示拉取后的状态
                            if repo.is_dirty():
                                self.log_message("⚠ 拉取后工作目录有未提交的更改，可能需要手动处理")
                            else:
                                self.log_message("✓ 拉取完成，工作目录干净")
                        else:
                            self.log_message(f"⚠ 远程分支 {remote_branch} 不存在")
                            
                    except Exception as e:
                        error_msg = f"从 {remote.name} 拉取失败: {str(e)}"
                        self.log_message(error_msg)
                        self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
                        continue
                
                self.log_message("拉取操作完成")
                self.root.after(0, lambda: messagebox.showinfo("成功", "拉取远程更新完成！"))
                
            except Exception as e:
                error_msg = f"拉取失败: {str(e)}"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
        
        threading.Thread(target=run_pull, daemon=True).start()
    
    def force_sync_remote(self):
        """强制同步远程仓库 - 防止自动创建分支"""
        def run_force_sync():
            repo = self.get_repo()
            if not repo:
                return
            
            try:
                self.log_message("=== 开始强制同步远程仓库 ===", "operation")
                
                # 检查是否有远程仓库
                if not repo.remotes:
                    self.log_message("当前仓库没有配置远程仓库")
                    self.root.after(0, lambda: messagebox.showwarning("警告", "当前仓库没有配置远程仓库"))
                    return
                
                # 获取当前分支
                current_branch = repo.active_branch.name
                self.log_message(f"当前分支: {current_branch}")
                
                # 显示同步选项
                sync_options = [
                    "1. 安全重置（推荐，不会创建分支）",
                    "2. 强制合并（可能创建分支）",
                    "3. 备份后重置（最安全）"
                ]
                
                option_text = "\n".join(sync_options)
                result = messagebox.askyesnocancel(
                    "强制同步选项",
                    f"检测到本地和远程仓库有不相关的历史记录。\n\n"
                    f"请选择同步方式：\n\n"
                    f"{option_text}\n\n"
                    f"选择：\n"
                    f"• 是：选项1（安全重置，推荐）\n"
                    f"• 否：选项2（强制合并）\n"
                    f"• 取消：选项3（备份后重置）"
                )
                
                if result is True:  # 是 - 安全重置（推荐）
                    try:
                        self.log_message("使用安全重置方式...", "operation")
                        for remote in repo.remotes:
                            remote_branch_ref = f"{remote.name}/{current_branch}"
                            self.log_message(f"重置到 {remote_branch_ref}...", "operation")
                        repo.git.reset("--hard", remote_branch_ref)
                        self.log_message(f"✓ 重置成功，不会创建额外分支")
                        
                        self.root.after(0, lambda: messagebox.showinfo("同步完成", 
                            "强制同步完成！\n\n"
                            "✓ 本地已重置到远程状态\n"
                            "✓ 没有创建额外分支\n"
                            "⚠ 注意：本地提交历史已丢失"))
                        
                    except Exception as e:
                        error_msg = f"安全重置失败: {str(e)}"
                        self.log_message(error_msg)
                        self.root.after(0, lambda: messagebox.showerror("同步失败", error_msg))
                        return
                
                elif result is False:  # 否 - 强制合并
                    try:
                        for remote in repo.remotes:
                            self.log_message(f"尝试强制合并 {remote.name}...", "operation")
                            try:
                                # 先尝试普通拉取
                                remote.pull(current_branch)
                                self.log_message(f"✓ 普通拉取成功")
                            except git.exc.GitCommandError as e:
                                if "refusing to merge unrelated histories" in str(e):
                                    self.log_message("检测到不相关历史，使用强制合并...", "operation")
                                    repo.git.pull(remote.name, current_branch, "--allow-unrelated-histories")
                                    self.log_message(f"✓ 强制合并成功")
                                else:
                                    raise e
                        
                        self.root.after(0, lambda: messagebox.showinfo("同步完成", 
                            "强制同步完成！\n\n"
                            "✓ 本地和远程历史已合并"))
                        
                    except Exception as e:
                        error_msg = f"强制合并失败: {str(e)}"
                        self.log_message(error_msg)
                        self.root.after(0, lambda: messagebox.showerror("同步失败", error_msg))
                        return
                
                else:  # 取消 - 备份后重置
                    try:
                        self.log_message("创建备份分支...", "operation")
                        backup_branch = f"backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
                        repo.git.checkout("-b", backup_branch)
                        self.log_message(f"✓ 已创建备份分支: {backup_branch}")
                        
                        # 切回原分支
                        repo.git.checkout(current_branch)
                        
                        # 重置到远程状态
                        for remote in repo.remotes:
                            remote_branch_ref = f"{remote.name}/{current_branch}"
                            self.log_message(f"重置到 {remote_branch_ref}...", "operation")
                        repo.git.reset("--hard", remote_branch_ref)
                        self.log_message(f"✓ 重置成功")
                        
                        self.root.after(0, lambda: messagebox.showinfo("同步完成", 
                            f"强制同步完成！\n\n"
                            f"• 本地更改已备份到分支: {backup_branch}\n"
                            f"• 当前分支已重置到远程状态\n\n"
                            f"如需恢复本地更改，请切换到 {backup_branch} 分支"))
                        
                    except Exception as e:
                        error_msg = f"备份后重置失败: {str(e)}"
                        self.log_message(error_msg)
                        self.root.after(0, lambda: messagebox.showerror("同步失败", error_msg))
                        return
                
                self.log_message("=== 强制同步完成 ===")
                
                # 刷新状态显示
                self.update_repo_status()
                
            except Exception as e:
                error_msg = f"强制同步失败: {str(e)}"
                self.log_message(error_msg)
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
        
        threading.Thread(target=run_force_sync, daemon=True).start()
    
    def one_click_push(self):
        """一键推送（add + commit + push）"""
        def run_one_click():
            repo = self.get_repo()
            if not repo:
                return
            
            try:
                self.log_message("开始一键推送...", "operation")
                
                # 1. 添加所有文件
                self.log_message("1. 添加所有文件...", "operation")
                repo.index.add('*')
                
                # 显示添加的文件列表
                self.log_message("已添加以下文件:")
                try:
                    # 获取已暂存的文件
                    staged_files = []
                    
                    # 获取已修改的文件
                    for item in repo.index.diff('HEAD'):
                        if item.a_path:
                            staged_files.append(("修改", item.a_path))
                    
                    # 获取新添加的文件
                    for item in repo.index.diff('HEAD', staged=True):
                        if item.a_path and item.a_path not in [f[1] for f in staged_files]:
                            staged_files.append(("新增", item.a_path))
                    
                    # 如果没有找到文件，尝试其他方法
                    if not staged_files:
                        # 检查工作目录状态
                        if repo.is_dirty():
                            # 获取已修改的文件
                            for item in repo.index.diff(None):
                                if item.a_path:
                                    staged_files.append(("修改", item.a_path))
                            
                            # 获取未跟踪的文件
                            for item in repo.untracked_files:
                                staged_files.append(("新增", item))
                    
                    # 显示文件列表
                    if staged_files:
                        for file_type, file_path in staged_files:
                            self.log_message(f"  {file_type}：{file_path}", "file_list")
                    else:
                        self.log_message("  没有检测到文件")
                        
                except Exception as e:
                    self.log_message(f"  获取文件列表时出错: {str(e)}")
                
                # 2. 检查是否有更改
                if not repo.is_dirty() and not repo.untracked_files:
                    self.log_message("没有需要提交的更改")
                    return
                
                # 3. 设置用户信息
                if self.username_var.get():
                    repo.config_writer().set_value("user", "name", self.username_var.get()).release()
                if self.email_var.get():
                    repo.config_writer().set_value("user", "email", self.email_var.get()).release()
                
                # 4. 提交
                commit_msg = self.commit_msg_var.get().strip()
                if not commit_msg:
                    commit_msg = "更新代码"
                
                self.log_message("2. 提交更改...", "operation")
                repo.index.commit(commit_msg)
                
                # 5. 推送
                self.log_message("3. 推送到远程...", "operation")
                current_branch = repo.active_branch.name
                for remote in repo.remotes:
                    remote.push(current_branch)
                
                self.log_message("一键推送完成！")
                
            except Exception as e:
                self.log_message(f"错误: {str(e)}")
        
        threading.Thread(target=run_one_click, daemon=True).start()

def main():
    root = tk.Tk()
    app = GiteeUploader(root)
    root.mainloop()

if __name__ == "__main__":
    main() 